﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Genealogy_Builder
{
    public partial class TreeViewer : Form
    {
        List<Person> People;
        List<Relation> Relations;

        int width, height;

        public TreeViewer()
        {
            InitializeComponent();
            People = new List<Person>();
            width = 800;
            height = 600;
        }

        public string ConstructScripts()
        {
            StringBuilder scriptVal = new StringBuilder(
                "var redraw, g, renderer;" +
                "window.onload = function() {" +
                "g = new Graph();");

            foreach (Person p in People)
            {
                scriptVal.Append("g.addNode('" + p.pid + "', {label:'" + p.name + "'});");
            }

            width = (150 * People.Count);
            height = 1000;

            scriptVal.Append("var width = " + width + "; var height = " + height + ";");

            int marriageCounter = 0;

            Dictionary<KeyValuePair<Person, Person>, int> marriageMarkers = new Dictionary<KeyValuePair<Person, Person>, int>();

            foreach (Relation r in Relations) //loop through and add marriages first
            {
                if ((r.type.ToLower() == "marriage" || r.type.ToLower() == "divorced") && People.Contains(r.person_a) && People.Contains(r.person_b))
                {
                    scriptVal.Append("g.addNode('m" + marriageCounter + "', {label:'" + r.type + "'});");
                    scriptVal.Append("g.addEdge('" + r.person_a.pid + "', 'm" + marriageCounter + "', {directed:true, stroke : '#ff0000'});");
                    scriptVal.Append("g.addEdge('" + r.person_b.pid + "', 'm" + marriageCounter + "', {directed:true, stroke : '#ff0000'});");
                    scriptVal.Append("g.addEdge('" + r.person_a.pid + "', '" + r.person_b.pid + "', {directed:true, stroke : '#ffffff'});"); //connect them for visual goodness, line is invisible

                    marriageMarkers.Add(new KeyValuePair<Person, Person>(r.person_a, r.person_b), marriageCounter);

                    marriageCounter++;
                }
            }

            foreach (Relation r in Relations) //loop through and add marriages first
            {
                if ((r.type.ToLower() == "parent-child") && People.Contains(r.person_a) && People.Contains(r.person_b))
                {
                    bool HasParentalPair = false;
                    foreach (Relation p in Relations)
                    {
                        if(p.person_b == r.person_b){
                            if (marriageMarkers.ContainsKey(new KeyValuePair<Person, Person>(r.person_a, p.person_a)))
                            {
                                HasParentalPair = true;
                                scriptVal.Append("g.addEdge('m" + marriageMarkers[new KeyValuePair<Person, Person>(r.person_a, p.person_a)] + "', '" + p.person_b.pid + "', {directed:true, stroke : '#0000ff'});");
                            }
                            else if (marriageMarkers.ContainsKey(new KeyValuePair<Person, Person>(p.person_a, r.person_a))) //check both possibilities
                            {
                                HasParentalPair = true;
                                scriptVal.Append("g.addEdge('m" + marriageMarkers[new KeyValuePair<Person, Person>(p.person_a, r.person_a)] + "', '" + p.person_b.pid + "', {directed:true, stroke : '#0000ff'});");
                            }
                        }
                    }

                    if (HasParentalPair == false) //single parent, father/mother unknown?
                    {
                        scriptVal.Append("g.addEdge('" + r.person_a.pid + "', '" + r.person_b.pid + "', {directed:true, stroke : '#0000ff'});");
                    }
                }
            }

            scriptVal.Append("var layouter = new Graph.Layout.Ordered(g, generation_sort(g)); renderer = new Graph.Renderer.Raphael('canvas', g, width, height);}");

            return scriptVal.ToString();
        }

        public bool Make(List<Person> lPeople, List<Relation> lRelations)
        {
            People = lPeople;
            Relations = lRelations;

            viewBox.DocumentText = "<html>"+
                "<head>" +
                    "<script type=\"text/javascript\" src=\"" + System.IO.Directory.GetCurrentDirectory() + "/graphing/raphael-min.js\"></script>" +
                    "<script type=\"text/javascript\" src=\"" + System.IO.Directory.GetCurrentDirectory() + "/graphing/dracula_graffle.js\"></script>" +
                    "<script type=\"text/javascript\" src=\"" + System.IO.Directory.GetCurrentDirectory() + "/graphing/jquery-1.4.2.min.js\"></script>" +
                    "<script type=\"text/javascript\" src=\"" + System.IO.Directory.GetCurrentDirectory() + "/graphing/dracula_graph.js\"></script>" +
                    "<script type=\"text/javascript\" src=\"" + System.IO.Directory.GetCurrentDirectory() + "/graphing/quicksort.js\"></script>" +
                    "<script type=\"text/javascript\" src=\"" + System.IO.Directory.GetCurrentDirectory() + "/graphing/dracula_algorithms.js\"></script>" +
                    "<script type=\"text/javascript\">" + ConstructScripts() + "</script>" +
                "</head>" +
                "<body>" +
                "<div id=\"canvas\"></div>" +
                "</body>" +
                "</html>";

            this.Width = 1000;
            this.Height = 800;

            //temporary

            saveToolStripMenuItem_Click_1(null, null);
            System.Diagnostics.Process.Start(saveLocationDialog.SelectedPath + "/index.html");
            return true;

            this.Show();

            return true;
        }

        private void viewBox_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        private void TreeViewer_Load(object sender, EventArgs e)
        {

        }

        private void fileToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            screenshotDialog.ShowDialog();
            if (screenshotDialog.FileName != null)
            {

                Bitmap bmp = new Bitmap(width, height);
                Rectangle bmpRect = new Rectangle(0, 0, width, height);

                viewBox.DrawToBitmap(bmp, bmpRect);

                System.Drawing.Image img = bmp;

                img.Save(screenshotDialog.FileName, System.Drawing.Imaging.ImageFormat.Png);
                img.Dispose();

                /*Currently not working, won't capture the canvas area*/
            }
        }

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            viewBox.Print();
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void saveToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            saveLocationDialog.ShowDialog();
            System.IO.File.WriteAllText(saveLocationDialog.SelectedPath + "/index.html", viewBox.DocumentText);
        }
    }
}
